#ifndef __DEBUG_H_INCLUDED__
#define __DEBUG_H_INCLUDED__

#include <iostream>
#include <fstream>
#include <time.h>
#include <sys/file.h>
#include "Bloqueable.h"


class DBG : public Bloqueable{
	void bloquear(){
		flock(1,LOCK_EX);
		if(echo)
			std::cout << timestamp();
		stream << timestamp();
	}
	void desbloquear(){
		flock(1,LOCK_UN);
		if(echo)
			std::cout<< std::flush;
		stream << std::flush;

	}
private:
	std::ofstream stream;
	bool echo;
public:
	DBG(){
		stream.exceptions(std::ios_base::goodbit);
	}
	
	void setArchivo(const char* nombre){
		stream.close();
		stream.open(nombre,std::ios_base::out|std::ios_base::trunc);
	}
	
	void setEcho(bool state){
		echo = state;
	}

	std::string timestamp(){
		std::string stamp("<");
		time_t t;
		time(&t);
		stamp += ctime(&t);
		stamp.erase(stamp.end()-1); //borro el \n
		stamp += "> ";
		return stamp;
	}

	DBG& operator<<(std::ostream& stream){
		if(echo)
			std::cout << stream;
		stream << stream;
		return *this;
	}

	DBG& operator<<(std::string &s){
		if(echo)
			std::cout << s;
		stream << s;
		return *this;
	}

	DBG& operator<<(int i){
		if(echo)
			std::cout << i ;
		stream << i;
		return *this;
	}


	DBG& operator<<(const char* s){
		if(echo)
			std::cout << s;
		stream << s;
		return *this;
	}
};
namespace std{
	extern DBG dbg;
}
#endif //__DEBUG_H_INCLUDED__
